Restful一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制:
CORS CORS是现代浏览亲支持快于请求的一种方式,全称是“跨域资源共享“(Cross-origin resource sharing),当使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源测率,会给该请求头:Origin,后台进行以系列处理,如果确定请求则在返回结果加入一个响应头:Access-Control-Allow-Origin;浏览器判断该响应头中是否包含Origin的值,如果有浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器之间驳回,这时我们无法拿到响应数据
JWT :Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密;
FastDFS :FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制, 充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文 件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。
[TOC]
Django认证系统|跨域请求|Celery
提供了用户模型类User和User的相关操作方法。
自定义User模型类之后,需要设置配置项AUTH_USER_MODEL
。
1. 前后端域名设置
域名和IP是对应的关系。
DNS解析:获取域名对应的IP
通过域名访问网站时,先到本地的hosts中查找IP和域名的对应关系,如果查到直接根据IP访问网站,如果查不到再进行DNS域名解析。
前端服务器域名: www.meiduo.site
后端API服务器域名:api.meiduo.site
2. 短信验证码
1 | URL: GET /sms_codes/(?P<mobile>1[3-9]\d{9})/ |
3. 跨域请求
浏览器的同源策略: 协议、主机IP和端口PORT相同的地址是同源,否则是非同源。
当发起请求的页面地址和被请求的地址不是同源,那么这个请求就是跨域请求。
在发起请求时,如果浏览器发现请求是跨域请求,那么在请求的报文头中,会添加如下信息:
Origin: 源请求IP地址
例如:Origin: http://www.meiduo.site:8080
在被请求的服务器返回的响应中,如果响应头中包含如下信息:
Access-Control-Allow-Origin: 源请求IP地址
例如:Access-Control-Allow-Origin: http://www.meiduo.site:8080
那么浏览器认为被请求服务器支持来源地址对其进行跨域请求,否则认为不支持,浏览器会将请求直接驳回。
Django跨域请求扩展使用。
4. celery异步任务队列
本质:
使用进程或协程调用函数实现异步。
基本概念:
发出者:发出所有执行的任务(任务就是函数)。
(中间人)任务队列:存放所要执行的任务信息。
处理者:也就是工作的进程或协程,负责监听任务队列,发现任务便执行对应的任务函数。
特点:
1)任务发送者和处理者可以分布在不同的电脑上,通过中间人进行信息交换。
2)任务队列中的任务会进行排序,先添加的任务会被先执行。
使用:
1)安装 pip install celery
2)创建Celery对象并配置中间人地址
from celery import Celery
celery_app = Celery(‘demo’)
配置文件:broker_url=’中间人地址’
celery_app.config_from_object(‘配置文件路径’)
3)定义任务函数
@celery_app.task(name=’my_first_task’)
def my_task(a, b):
print(‘任务函数被执行’)
…
4)启动worker
celery -A ‘celery_app文件路径’ worker -l info
5)发出任务
my_task.delay(2, 3)
5. 用户注册
1 | URL: POST /users/ |
补充(axios请求发送)
1 | axios.get('url地址', [config]) |
注册|JWT Token|普通登录
1. 用户注册
1 | URL: POST /users/ |
创建新用户:User.objects.create_user(username, email=None, password=None, *\extra_fields*)
2. JWT token
1)session认证
1 | 1. 接收用户名和密码 |
session认证的一些问题:
- session存储在服务器端,如果登录的用户过多,服务器开销比较大。
- session依赖于cookie,session的标识存在cookie中,可能会有CSRF(跨站请求伪造)。
2)jwt 认证机制(替代session认证)
1 | 1. 接收用户名和密码 |
如果之后需要进行身份认证,客户端需要将jwt token发送给服务器,由服务器验证jwt token的有效性。
3)jwt 的数据格式
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik |
a)headers头部
1 | { |
base64加密(很容易被解密)
b)payload(载荷):用来保存有效信息
1 | { |
base64加密
c)signature(签名):防止jwt token被伪造
将headers和payload进行拼接,用.隔开,使用一个密钥(secret key)进行加密,加密之后的内容就是签名。
jwt token是由服务器生成,密钥保存在服务器端。
3. jwt 扩展签发jwt token
1 | from rest_framework_jwt.settings import api_settings |
4. 用户登录
1)jwt 扩展的登录视图obtain_jwt_token:
接收username和password,进行用户名和密码验证,正确情况下签发jwt token并返回给客户端。
2)更改obtain_jwt_token组织响应数据的函数:
1 | def jwt_response_payload_handler(token, user=None, request=None): |
3)登录支持用户名和手机号
1 | obtain_jwt_token |
自定义Django的认证系统后端,同时设置配置项AUTHENTICATION_BACKENDS
。
##QQ登录
1. QQ登录-预备工作
1)成为QQ开发者
2)创建开发者应用
3)查询QQ登录开发文档
2. QQ登录-开发关键点
获取QQ登录用户的唯一身份标识(openid),然后根据openid进行处理。
判断该QQ用户是否绑定过本网站的用户,如果绑定过,直接登录,如果未绑定过,先进行绑定。
QQ用户绑定: 将openid 和 用户user_id 对应关系存下来。
id | user_id | openid |
---|---|---|
1 | 2 | Akdk19389kDkdkk99939kdk |
2 | 2 | AKdkk838e8jdiafkdkkFKKKFf |
注:一个用户可以绑定多个qq账户。
3. QQ登录API
1)获取QQ登录网址API
1 | API: GET /oauth/qq/authorization/?next=<url> |
2)获取QQ登录用户openid并进行处理API
1 | API: GET /oauth/qq/user/?code=<code> |
3)绑定QQ登录用户的信息API
1 | API: POST /oauth/qq/user/ |
###4. 相关模块的使用
1 | # 将python字典转化为查询字符串 |
邮件发送|省市三级联动
个人信息获取
1)给User添加email_active
字段,用于记录邮箱email
是否被激活。
2)API接口:获取用户个人信息。
1 | 请求方式和URL地址: GET /user/ |
3)使用RetrieveAPIView时,其获取单个对象时是根据pk获取,我们这里所有获取的是当前登录的用户,所以需要把get_object
方法进行重写。
4)request对象的user属性。
对于request对象,有一个user属性。这个user属性:
a)如果用户认证成功,request.user
是User模型类的实例对象,存放的是当前登录用户的信息。
b)如果用户未认证,request.user
是AnonymousUser
类的实例对象。
###用户邮箱设置
1)API接口:设置用户个人邮箱。
1 | 请求方式和URL地址: PUT /email/ |
2)处理流程:
a)接收参数并进行校验(email是否传递,格式是否正确)
b)保存用户的邮箱信息并发送激活邮件
c)返回应答,设置邮箱成功
3)发送激活邮件
a)生成激活链接:在激活链接中需要保存待激活用户的id和email,但是为了安全,需要对信息进行加密。
b)发送邮件:配置文件中先进行邮件发送配置,在使用django的send_mail方法发送邮件,为了不影响邮件设置过程,邮件采用celery发送。
1 | from django.core.mail import send_mail |
个人邮箱激活
1)API接口:激活用户个人邮箱。
1 | 请求方式和URL地址: GET /emails/verification/?token=xxx |
2)处理流程:
a)接收参数token并进行校验(token是否传递,token是否有效)
b)将用户邮箱激活标记设置为已激活。
c)返回应答,邮箱激活成功。
省市县三级信息
1)信息存储(自关联) 地区的自关联其实是一个特殊一对多的关系。
一个省包含很多个市,一个市包含很多县。
id(地区id) | name(地区名) | parent_id(父级地区ID) |
---|---|---|
320000 | 江苏省 | NULL |
320200 | 无锡市 | 320000 |
320282 | 宜兴市 | 320200 |
2)模型类自关联(地区的自关联其实是一个特殊的一对多)
1 | class Area(models.Model): |
注:模型类自关联,ForeignKey第一个参数传self
。
另外之前的关联查询中,有了一个area对象之后,查询关联的下级地区信息和父级地区,例如:
1 | area = Area.objects.get(id='320200') |
当ForeignKey创建关联属性时,指定了related_name='subs'
之后,再查询和area对象关联的子级地区,不在使用area.area_set.all()
,而是使用area.subs.all()
。
3)定义导入地区信息shell脚本
1 |
|
4)地区视图集。
补充(客户端发送请求时携带JWT token数据)
1 | axios.get(this.host + '/user/', { |
最后更新: 2019年03月14日 14:28
原始链接: https://zem12345678.github.io/2019/03/13/Django Restful Framework(DRF)的开发思考(2)/